# cython: language_level=3
import json
import os
import time
import uuid
from typing import Annotated

from fastapi import APIRouter, Header, Depends
from gmssl import sm3, func

from app.middlewares.redis import get_redis
from common.log import get_logger
from common.redis import MyRedis

router = APIRouter(tags=["token"])

token_map = {}

logger = get_logger("server")


def sm3_hash(data):
    """
    SM3生成64位小写签名串
    """
    data_sm3_hash = sm3.sm3_hash(func.bytes_to_list(data.encode("utf-8")))
    logger.info(data_sm3_hash)

    return data_sm3_hash


def check_sign(app_id, sign):
    """
    检查签名
    从系统中拿出 app_secret ，跟请求中的appid加密生成sign（正确的），跟请求中的签名串对比，不一样说明验证不能通过
    """
    app_secret = os.getenv("APP_SECRET")
    temp_token = app_id + app_secret
    encrypted_token = sm3_hash(temp_token)
    logger.debug("正确的sign: {}", encrypted_token)
    logger.debug("请求中传过来的sign: {}", sign)
    if encrypted_token != sign:
        return False
    return True


def check_authorization(app_id, token, sign, redis: MyRedis):
    """
    检查接口的授权
    """
    if not check_sign(app_id, sign):
        return False
    now_time = time.time()
    temp_token = redis.get_token(app_id)
    if temp_token is None:
        return False
    temp_token = json.loads(temp_token)
    if temp_token["token"] != token:
        return False
    if temp_token["expire"] < now_time:
        return False
    return True


def generate_token():
    """
    生成 token
    """
    token = uuid.uuid1().hex
    return token


@router.post("/getToken")
def get_token(
        authorization: Annotated[str | None, Header()] = None,
        redis: MyRedis = Depends(get_redis),
):
    """
    获取 token
    """
    # logger.info("打印一下认证信息看看：,{authorization}")
    logger.debug("打印一下认证信息看看：{}", authorization)
    authorization_json = json.loads(authorization)

    app_id = authorization_json.get("appId")
    sign = authorization_json.get("sign")
    if not check_sign(app_id, sign):
        return {"success": False, "code": "401", "message": "Unauthorized"}

    token = generate_token()
    pk = os.getenv("PUBLIC_KEY")
    # 30min 后过期
    expire_time = time.time() + 30 * 60
    redis.set_token(app_id, json.dumps({"token": token, "expire": expire_time}))
    return {
        "success": True,
        "code": "200",
        "message": "登录成功",
        "data": {"token": token, "pk": pk},
    }
